﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Resources;
using System.Threading;
using System.Windows.Forms;
using PCSComProduct.Items.DS;
using PCSComProduction.WorkOrder.BO;
using PCSComProduction.WorkOrder.DS;
using PCSComUtils.Common;
using PCSComUtils.Common.BO;
using PCSComUtils.PCSExc;
using PCSUtils.Log;
using PCSUtils.Utils;
using PCSComUtils.DataContext;
using System.Collections.Generic;
using System.Reflection;
using System.Collections.Specialized;

namespace PCSProduction.WorkOrder
{
    public partial class TinhGiaThanhKeHoachForKMP : Form
    {
        private const string THIS = "PCSProduct.Items.ProductItemInfo";
        private int intProductID;
        public TinhGiaThanhKeHoachForKMP()
        {
            InitializeComponent();
        }

        private void TinhGiaThanhKeHoachForKMP_Load(object sender, EventArgs e)
        {

        }

        private void btnProductCode_Click(object sender, EventArgs e)
        {
            const string METHOD_NAME = THIS + ".btnProductCode_Click()";
            try
            {
                DataRowView drwResult = null;
                Hashtable htbConditon = new Hashtable();
                
                drwResult = FormControlComponents.OpenSearch(ITM_ProductTable.CODE_FLD, txtCode.Text, ITM_ProductTable.PRODUCTID_FLD, ITM_ProductTable.TABLE_NAME, htbConditon, true, false);
                if (drwResult != null)
                {
                    intProductID = int.Parse(drwResult[ITM_ProductTable.PRODUCTID_FLD].ToString());
                    txtCode.Tag = drwResult[ITM_ProductTable.PRODUCTID_FLD];
                    txtCode.Text = drwResult[ITM_ProductTable.CODE_FLD].ToString();
                }
            }
            catch (Exception ex)
            {
                // displays the error message.
                PCSMessageBox.Show(ErrorCode.OTHER_ERROR, MessageBoxIcon.Error);
                // log message.
                try
                {
                    Logger.LogMessage(ex, METHOD_NAME, Level.ERROR);
                }
                catch
                {
                    PCSMessageBox.Show(ErrorCode.LOG_EXCEPTION, MessageBoxIcon.Error);
                }
            }
        }

        private void btnExcel_Click(object sender, EventArgs e)
        {
            TinhGiaThanhKeHoachForKMPBO objBO = new TinhGiaThanhKeHoachForKMPBO();
            DataTable dtbReportData = new DataTable();

            DataTable dtbTop = new DataTable("MaterialReport");
            if (intProductID > 0)
                dtbTop = objBO.GetOneItem(intProductID);

            DataTable dtbAllChild = objBO.GetAllItems();
            dtbReportData = dtbTop.Clone();
            foreach (DataRow drowData in dtbTop.Rows)
                BuildData(dtbReportData, dtbAllChild, drowData, 0, SystemProperty.CCNID, 0);
            // add number list
            dtbReportData = AddNumberedListToDataTable(dtbReportData);
            DataTable dtb = dtbReportData.Copy();
            dtb.Clear();
            //Lay thuoc tinh cua product
            DataSet dsetAtr = objBO.GetAtrib();
            if (dsetAtr != null && dsetAtr.Tables.Count > 0)
            {
                if (dtbReportData != null)
                {
                    foreach (DataRow dr in dtbReportData.Rows)
                    {
                        if (dr["ProductID"] != DBNull.Value)
                        {
                            foreach (DataRow dr1 in dsetAtr.Tables[0].Rows)
                            {
                                if (dr1["ProductID"] != DBNull.Value && Convert.ToInt32(dr1["ProductID"])==Convert.ToInt32(dr["ProductID"]))
                                {
                                    dr["MaterialExpense"] = dr1["MaterialExpense"];
                                    dr["OutSideExpense"] = dr1["OutSideExpense"];
                                    dr["CostPerMin"] = dr1["CostPerMin"];
                                   
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            DataRow[] drowChidl = dtbReportData.Select(" ParentID <>0");
            //Tìm lá cuối cùng
            foreach (DataRow dr in drowChidl)
            {
                DataRow drowItem = dtb.NewRow();
                foreach (DataColumn dcolData in dtb.Columns)
                    drowItem[dcolData.ColumnName] = dr[dcolData.ColumnName];
                DataRow[] drowsChild1 = GetChild(dtbReportData, int.Parse(dr["ProductID"].ToString()));
                if (drowsChild1.Length <= 0)
                {
                    dtb.Rows.Add(drowItem);
                }
            }
            
            if (dtb.Rows.Count > 0)
            {
                #region Tinh gia thang goc
                foreach (DataRow drParent in dtbReportData.Rows)
                {
                    if (drParent["ParentID"] == DBNull.Value)
                    {
                        foreach (DataRow drChidl in dtb.Rows)
                        {
                            if (drParent["MaterialExpense"] != DBNull.Value)
                            {
                                if (drChidl["MaterialExpense"] != DBNull.Value)
                                {
                                    drParent["MaterialExpense"] = Convert.ToDecimal(drParent["MaterialExpense"]) + Convert.ToDecimal(drChidl["MaterialExpense"]);
                                }
                            }
                            else
                            {
                                if (drChidl["MaterialExpense"] != DBNull.Value)
                                {
                                    drParent["MaterialExpense"] = Convert.ToDecimal(drChidl["MaterialExpense"]);
                                }
                            }

                        }
                    }
                }
                #endregion
                #region Tinh gia cho thang goc tiep theo
                foreach (DataRow dr in dtb.Rows)
                {
                    foreach (DataRow dr1 in dtbReportData.Rows)
                    {
                        if (dr1["ParentID"] != DBNull.Value)
                        {
                            string iProductID = dr1["ProductID"].ToString();
                            string strParentID = dr["ParentID"].ToString();
                            if (iProductID == strParentID)
                            {
                                if (dr1["MaterialExpense"] != DBNull.Value)
                                {
                                    if (dr["MaterialExpense"] != DBNull.Value)
                                    {
                                        dr1["MaterialExpense"] = Convert.ToDecimal(dr1["MaterialExpense"]) + Convert.ToDecimal(dr["MaterialExpense"]);
                                    }
                                }
                                else
                                {
                                    if (dr["MaterialExpense"] != DBNull.Value)
                                    {
                                        dr1["MaterialExpense"] = Convert.ToDecimal(dr["MaterialExpense"]);
                                    }
                                }
                            }
                        }
                    }
                }
                #endregion

            }
            DataRow[] drow = dtbReportData.Select("", "NumberedList DESC");
            foreach (DataRow dr in drow)
            {
                DataRow[] drChidl = dtbReportData.Select("ParentID=" + dr["ProductID"].ToString());
                decimal d = 0;
                decimal dOutSideExpense = 0;
                decimal dCostPerMin = 0;
                decimal dPurchaseunitprice = 0;
               
                if (drChidl.Length > 0)
                {
                    foreach (DataRow dr1 in drChidl)
                    {
                        if (dr1["MaterialExpense"] != DBNull.Value)
                        {
                            d += Convert.ToDecimal(dr1["MaterialExpense"]);
                        }
                        if (dr1["OutSideExpense"] != DBNull.Value)
                        {
                            dOutSideExpense += Convert.ToDecimal(dr1["OutSideExpense"]);
                        }
                        if (dr1["CostPerMin"] != DBNull.Value)
                        {
                            dCostPerMin += Convert.ToDecimal(dr1["CostPerMin"]);
                        }
                        if (dr1["Purchaseunitprice"] != DBNull.Value)
                        {
                            dPurchaseunitprice += Convert.ToDecimal(dr1["Purchaseunitprice"]);
                        }
                    }
                    dr["MaterialExpense"] = d;
                    dr["OutSideExpense"] = dOutSideExpense;
                    dr["CostPerMin"] = dCostPerMin;
                    dr["Purchaseunitprice"] = dPurchaseunitprice;
                }
            }
            foreach (DataRow dr in drow)
            {
                foreach (DataRow dr1 in dtbReportData.Rows)
                {
                    if (dr1["ProductID"].ToString() == dr["ProductID"].ToString())
                    {
                        dr1["MaterialExpense"] = dr["MaterialExpense"];
                        dr["OutSideExpense"] = dr["OutSideExpense"];
                        dr["CostPerMin"] = dr["CostPerMin"];
                        dr["Purchaseunitprice"] = dr["Purchaseunitprice"];
                    }
                }
            }
           /* foreach (DataRow dr in dtbReportData.Rows)
            {
                //Tim cac thang con 
                if (dr["ParentID"] != DBNull.Value)
                {
                    DataRow[] drChidl = dtbReportData.Select("ParentID=" + dr["ProductID"].ToString());
                    decimal d = 0;
                    if (drChidl.Length > 0)
                    {
                        foreach (DataRow dr1 in drChidl)
                        {
                            if (dr1["MaterialExpense"] != DBNull.Value)
                            {
                                d += Convert.ToDecimal(dr1["MaterialExpense"]);
                            }
                        }
                        dr["MaterialExpense"] = d;
                    }
                }
            }*/
            PCSUtils.Utils.ExecuteReport objReport = new ExecuteReport();
            objReport.ExportExcelBaoGiaKeHoach(dtbReportData, "Template_Cost_ForKMP.xls", 3, 1);
        }
        
        private void BuildData(DataTable pdtbData, DataTable pdtbAllChild, DataRow pdrowNew, int pintLevel, int pintCCNID, int pintCategoryID)
        {
            try
            {
                DataRow drowItem = pdtbData.NewRow();
                foreach (DataColumn dcolData in pdtbData.Columns)
                    drowItem[dcolData.ColumnName] = pdrowNew[dcolData.ColumnName];
                drowItem["Level"] = pintLevel;
                pdtbData.Rows.Add(drowItem);
                // get child
                //DataTable dtbChild = GetChild(pintCCNID, pintCategoryID, int.Parse(drowItem[ITM_ProductTable.PRODUCTID_FLD].ToString()));
                DataRow[] drowsChild = GetChild(pdtbAllChild, int.Parse(drowItem["ProductID"].ToString()));
                foreach (DataRow drowChild in drowsChild)
                    BuildData(pdtbData, pdtbAllChild, drowChild, pintLevel + 1, pintCCNID, pintCategoryID);
            }
            catch(Exception ex)
            {
            }
        }
        private DataRow[] GetChild(DataTable pdtbAllChilds, int pintParentID)
        {
            try
            {
                DataRow[] drowResult = pdtbAllChilds.Select("ParentID = '" + pintParentID.ToString() + "'");
                return drowResult;
            }
            catch
            {
                return null;
            }
        }

        private DataTable AddNumberedListToDataTable(DataTable pdtb)
        {
            try
            {
                DataTable dtbRet = pdtb.Copy();

                DataColumn odcol = new DataColumn("NumberedList");
                odcol.DataType = typeof(string);
                odcol.DefaultValue = "";
                dtbRet.Columns.Add(odcol);

                int[] arriInputLevel = ExtractArrayOfLevelFromDataTable(pdtb);
                StringCollection arrNumberedList = GetNumberedListForBOMProduct(arriInputLevel, 0, ".");

                int intCount = 0;
                foreach (DataRow row in dtbRet.Rows)
                {
                    string strNumber = arrNumberedList[intCount];
                    string strPartNo = row["Part No."].ToString();
                    row["NumberedList"] = strNumber;
                    // indent the part no following the level
                    int intLevel = int.Parse(row["Level"].ToString());
                    for (int i = 0; i < intLevel; i++)
                        strPartNo = "- " + strPartNo;
                    row["Part No."] = strPartNo;
                    intCount++;
                }
                return dtbRet;
            }
            catch
            {
                return null;
            }
        }

        public static int[] ExtractArrayOfLevelFromDataTable(DataTable pdtb)
        {
            try
            {
                int[] arrintRet = new int[pdtb.Rows.Count];
                int intCount = 0;
                foreach (DataRow row in pdtb.Rows)
                {
                    arrintRet[intCount] = int.Parse(row["Level"].ToString());
                    intCount++;
                }
                return arrintRet;
            }
            catch
            {
                return null;
            }
        }

        public static StringCollection GetNumberedListForBOMProduct(int[] parriInput,
                                                                    int pintRootNumber,
                                                                    string pstrDeli)
        {
            try
            {
                #region DEFINE Variables

                StringCollection arrRet = new StringCollection();
                int intRecordCount = parriInput.Length;
                StringCollection arrParentString = new StringCollection();
                for (int intCounter = 0; intCounter < intRecordCount + 1; intCounter++)
                {
                    arrParentString.Add("");
                }
                int[] arriLevelHit = new int[intRecordCount + 1];

                #endregion

                int intPrev = pintRootNumber; // in start phase, iRootNumber is iPrev
                foreach (int i in parriInput)
                {
                    string strOut = "";
                    /// Update level hit count == active running number of last index
                    (arriLevelHit[i])++; // increase the hit count  of level i
                    arriLevelHit[i + 1] = 0; // reset hit count of level i+1 to ZERO

                    if (i == pintRootNumber) // if the level is restart to iRootNumber
                    {
                        // level 0, not exist
                        // Parent string of level iRootNumber, alway = ""
                        // strOut always = "1"
                        arrParentString[i] = "";
                        strOut = "1";
                    }
                    else
                    {
                        strOut = arrParentString[i] + pstrDeli + arriLevelHit[i];
                        if (strOut.StartsWith("."))
                            strOut = strOut.Remove(0, 1);
                    }
                    intPrev = i;
                    arrParentString[i + 1] = strOut;
                    arrRet.Add(strOut);
                }
                return arrRet;
            }
            catch
            {
                return null;
            }
        }

        private void txtCode_KeyPress(object sender, KeyPressEventArgs e)
        {
            const string METHOD_NAME = THIS + ".txtCode_KeyPress()";
            if (e.KeyChar == 13)
            {
                try
                {

                    DataRowView drwResult = null;
                    drwResult = FormControlComponents.OpenSearchForm(ITM_ProductTable.TABLE_NAME, ITM_ProductTable.CODE_FLD, txtCode.Text, null, false);
                    if (drwResult != null)
                    {
                        intProductID = int.Parse(drwResult[ITM_ProductTable.PRODUCTID_FLD].ToString());
                        txtCode.Tag = drwResult[ITM_ProductTable.PRODUCTID_FLD];
                        txtCode.Text = drwResult[ITM_ProductTable.CODE_FLD].ToString(); 
                    }
                   
                }
                catch (PCSException ex)
                {
                    // Displays the error message if throwed from PCSException.
                    PCSMessageBox.Show(ex.mCode, MessageBoxIcon.Error);
                    try
                    {
                        // Log error message into log file.
                        Logger.LogMessage(ex.CauseException, METHOD_NAME, Level.ERROR);
                    }
                    catch
                    {
                        // Show message if logger has an error.
                        PCSMessageBox.Show(ErrorCode.LOG_EXCEPTION, MessageBoxIcon.Error);
                    }
                }
                catch (Exception ex)
                {
                    // Displays the error message if throwed from system.
                    PCSMessageBox.Show(ErrorCode.OTHER_ERROR, MessageBoxIcon.Error);
                    try
                    {
                        // Log error message into log file.
                        Logger.LogMessage(ex, METHOD_NAME, Level.ERROR);
                    }
                    catch
                    {
                        // Show message if logger has an error.
                        PCSMessageBox.Show(ErrorCode.LOG_EXCEPTION, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
